package com.qzsoft.zhjd.materiel.modules.materielitem.service.impl;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qzsoft.zhjd.common.components.BaseServiceComponent;
import com.qzsoft.zhjd.common.enums.BizCode;
import com.qzsoft.zhjd.common.enums.YesOrNo;
import com.qzsoft.zhjd.common.utils.FunctionUtils;
import com.qzsoft.zhjd.common.utils.RenExceptionUtils;
import com.qzsoft.zhjd.materiel.modules.materielitem.dto.MaterielItemTreeDto;
import com.qzsoft.zhjd.materiel.modules.materieldata.entity.MaterielDataEntity;
import com.qzsoft.zhjd.materiel.modules.materieldata.service.MaterielDataService;
import com.qzsoft.zhjd.materiel.modules.materielitem.dto.MaterielItemListDto;
import com.qzsoft.zhjd.materiel.modules.materielitem.entity.MaterielItemEntity;
import com.qzsoft.zhjd.materiel.modules.materielitem.mapper.MaterielItemMapper;
import com.qzsoft.zhjd.materiel.modules.materielitem.service.MaterielItemBaseService;
import com.qzsoft.zhjd.materiel.modules.materielitem.service.MaterielItemService;

/**
 * @ClassName MaterielItemServiceImpl
 * @Description 数据字典业务接口实现
 * @author linhuawei
 * @since 2022-03-29
 */
@Service
public class MaterielItemServiceImpl extends ServiceImpl<MaterielItemMapper, MaterielItemEntity>
        implements MaterielItemService {

    @Autowired
    private BaseServiceComponent baseServiceComponent;

//    @Autowired
//    private MaterielApiService materielApiService;
//
//    @Autowired
//    private MaterielApiVesionService materielApiVesionService;

    @Autowired
    private MaterielDataService materielDataService;
    
    @Autowired
    private MaterielItemBaseService materielItemBaseService;

//    @Autowired
//    private MaterielItemService materielItemService;
//
//    @Value("${zhjd.upload.getItemInfo}")
//    private String getItemInfo;

    @Override
    public List<MaterielItemTreeDto> categoryTreeDto() {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("category", YesOrNo.yes.getValue());
        List<MaterielItemTreeDto> list = baseMapper.itemTree(params);

        List<MaterielItemTreeDto> result = new ArrayList<MaterielItemTreeDto>();
        if (null != list) {
            for (MaterielItemTreeDto dto : list) {
                if (null == dto.getPpkid()) {
                    dto.setChildren(categoryTreeChildren(list, dto.getPkid()));
                    result.add(dto);
                }
            }

        }
        return result;
    }

    @Override
    public IPage<MaterielItemListDto> itemPage(Map<String, Object> params) {
        IPage<MaterielItemListDto> page = baseServiceComponent.getPage(params, MaterielItemListDto.class);
        return baseMapper.itemPage(page, params);
    }

    @Override
    public MaterielItemEntity getItemByCustomId(String id) {
        QueryWrapper<MaterielItemEntity> queryWrapper = new QueryWrapper<MaterielItemEntity>();
        queryWrapper.eq("id", id);
        queryWrapper.eq("category", 0);// 不是材料类型
        queryWrapper.eq("weighed", 1);// 需要过磅
        queryWrapper.last(" LIMIT 0,1 ");
        return baseMapper.selectOne(queryWrapper);
    }

    @Override

    public boolean save(MaterielItemEntity entity) {
        // 校验材料主键
        check(entity);

        // 判断上级材料是否存在，上级材料是否分类类型
        String ppkid = entity.getPpkid();
        MaterielItemEntity temp = null;
        String code = "";
        if (null != ppkid) {
            temp = baseMapper.selectById(ppkid);
            if (null == temp || YesOrNo.no.getValue() == temp.getCategory()) {
                RenExceptionUtils.throwEx(BizCode.PARAMS_ERROR, "所属材料分类不存在");
            }
            code = temp.getCode();
        }

        // 生成材料编号
        QueryWrapper<MaterielItemEntity> queryWrapper = new QueryWrapper<MaterielItemEntity>();
        queryWrapper.select(" max(code) as code ");
        if (null == ppkid) {
            queryWrapper.isNull("ppkid");
        } else {
            queryWrapper.eq("ppkid", ppkid);
        }
        temp = baseMapper.selectOne(queryWrapper);
        if (null == temp) {
            code = code + "000";
        } else {
            String maxCode = temp.getCode();
            maxCode = maxCode.substring(maxCode.length() - 3, maxCode.length());
            int maxIdNum = Integer.parseInt(maxCode, 36);
            if (maxIdNum >= 46655) {
                RenExceptionUtils.throwEx(BizCode.PARAMS_ERROR, "当前层级以达到最大数量");
            }
            maxCode = Integer.toString(maxIdNum + 1, 36);
            if (1 == maxCode.length()) {
                maxCode = "00" + maxCode;
            } else if (2 == maxCode.length()) {
                maxCode = "0" + maxCode;
            }
            code = code + maxCode;
        }

        // 执行添加操作
        entity.setCode(code.toUpperCase());
        return super.save(entity);
    }

    @Override
    public boolean updateById(MaterielItemEntity entity) {
        // 判断材料是否存在
        MaterielItemEntity temp = baseMapper.selectById(entity.getPkid());
        if (null == temp) {
            RenExceptionUtils.throwEx(BizCode.PARAMS_ERROR, "材料信息不存在");
        }

        // 类型不可修改
        entity.setCategory(temp.getCategory());

        // 校验材料数据
        check(entity);

        // 执行修改操作
        return super.updateById(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeById(Serializable id) {
        // 获取要删除的数据
        MaterielItemEntity entity = baseMapper.selectById(id);
        if (null == entity) {
            return true;
        }

        // 判断下属是否有材料数据
        QueryWrapper<MaterielItemEntity> queryWrapper = new QueryWrapper<MaterielItemEntity>();
        queryWrapper.eq("ppkid", id);
        Integer count = baseMapper.selectCount(queryWrapper);
        if (null != count && 0 < count) {
            RenExceptionUtils.throwEx(BizCode.PARAMS_ERROR, "当前分类下属有材料信息，不可删除");
        }

        // 判断材料是否在用
        QueryWrapper<MaterielDataEntity> dataQueryWrapper = new QueryWrapper<MaterielDataEntity>();
        dataQueryWrapper.eq("materiel_item_id", entity.getId());
        count = materielDataService.count(dataQueryWrapper);
        if (null != count && 0 < count) {
            RenExceptionUtils.throwEx(BizCode.PARAMS_ERROR, "材料在用，不可删除");
        }
        
        // 删除材料，养护基地材料
        baseMapper.deleteById(id);
        materielItemBaseService.deleteByMaterielItemId(entity.getId());
        return true;
    }

    /**
     * @Title checkId
     * @Description 校验材料数据
     * @param entity
     */
    private void check(MaterielItemEntity entity) {
        // 判断是否过磅
        boolean validate = YesOrNo.includeValue(entity.getWeighed());
        if (!validate) {
            RenExceptionUtils.throwEx(BizCode.PARAMS_ERROR, "是否过磅错误");
        }

        // 判断是否分类
        validate = YesOrNo.includeValue(entity.getCategory());
        if (!validate) {
            RenExceptionUtils.throwEx(BizCode.PARAMS_ERROR, "是否分类错误");
        }

        // 如果不是分类，判断单位是否存在
        // 如果是分类，单位、规格设置为空
        if (YesOrNo.no.getValue() == entity.getCategory()) {
            if (ObjectUtils.isEmpty(entity.getUnit())) {
                RenExceptionUtils.throwEx(BizCode.PARAMS_ERROR, "材料单位不可为空");
            }
        } else {
            entity.setUnit(null);
            entity.setSpec(null);
        }

        // 材料名称、规格进行md5加密后作为主键
        String fullname = entity.getName();
        if (null != entity.getSpec()) {
            fullname = fullname + entity.getSpec();
        }
        String id = FunctionUtils.md5L32(fullname);

        // 判断是否重复
        QueryWrapper<MaterielItemEntity> queryWrapper = new QueryWrapper<MaterielItemEntity>();
        queryWrapper.eq("id", id);
        if (null != entity.getPkid()) {
            queryWrapper.ne("pkid", entity.getPkid());
        }
        Integer count = baseMapper.selectCount(queryWrapper);
        if (null != count && 0 < count) {
            RenExceptionUtils.throwEx(BizCode.PARAMS_ERROR, "材料[" + fullname + "]已经存在");
        }

        // 设置材料主键
        entity.setId(id);
    }

    @Override
    public List<MaterielItemTreeDto> weighedTree() {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("weighed", YesOrNo.yes.getValue());
        List<MaterielItemTreeDto> list = baseMapper.itemTree(params);

        List<MaterielItemTreeDto> result = new ArrayList<MaterielItemTreeDto>();
        if (null != list) {
            for (MaterielItemTreeDto dto : list) {
                if (null == dto.getPpkid()) {
                    dto.setChildren(categoryTreeChildren(list, dto.getPkid()));
                    result.add(dto);
                }
            }

        }
        return result;
    }

//    @Override
//    @Transactional(rollbackFor = Exception.class)
//    //访问url获取、存储材料字典
//    public void getUrlInfo() throws IOException {
//        //获取访问接口的url
//        String url = getItemInfo;
//        Map<String,Object> params = new HashMap<String,Object>();
//        //获取Version版本号
//        Long getItemList = materielApiVesionService.getVersionByCode("getItemList");
//        params.put("getItemList",getItemList);
//        //发送请求
//        String result = HttpUtil.get(url,params);
//        JSONObject resultJson = JSONObject.parseObject(result);
//        if(resultJson == null){
//            RenExceptionUtils.throwEx(BizCode.EXCEPTION, "传输数据格式不正确");
//        }
//        Integer status = resultJson.getInteger("code");
//        if(status != 200){
//            RenExceptionUtils.throwEx(BizCode.EXCEPTION, "请求失败");
//        }
//        JSONArray datas = resultJson.getJSONArray("data");
//        if(datas == null){
//            RenExceptionUtils.throwEx(BizCode.EXCEPTION, "返回数据格式异常");
//        }
//        //获取材料字典数据信息
//        List<RequestMaterialItemDto> items = datas.toJavaList(RequestMaterialItemDto.class);
//        //更新字典版本号
//        materielApiVesionService.updateByCode("getItemList");
//        //删除表中数据
//        materielItemService.remove(null);
//        //处理响应数据，存储材料字典
//        for(RequestMaterialItemDto item : items){
//            MaterielItemEntity materielItemEntity = new MaterielItemEntity();
//            materielItemEntity.setName(item.getName());
//            materielItemEntity.setId(item.getId());
//            materielItemEntity.setPkid(item.getPkid());
//            materielItemEntity.setCode(item.getCode());
//            materielItemEntity.setUnit(item.getUnit());
//            materielItemEntity.setCategory(item.getCategory());
//            materielItemEntity.setWeighed(item.getWeighed());
//
//            if (item.getPkid() != null) {
//                materielItemEntity.setPpkid(item.getPpkid());
//            }
//            materielItemEntity.setSpec(item.getSpec());
//            materielItemEntity.setRemark(item.getRemark());
//            materielItemService.save(materielItemEntity);
//        }
//        }


    /**
     * @Title categoryTreeChildren
     * @Description 处理类型树子节点数据
     * @param list 要处理的数据
     * @param pkid 上级主键
     * @return 子节点数据
     */
    private List<MaterielItemTreeDto> categoryTreeChildren(List<MaterielItemTreeDto> list, String pkid) {
        List<MaterielItemTreeDto> result = new ArrayList<MaterielItemTreeDto>();
        for (MaterielItemTreeDto dto : list) {
            if (pkid.equals(dto.getPpkid())) {
                dto.setChildren(categoryTreeChildren(list, dto.getPkid()));
                result.add(dto);
            }
        }
        return result;
    }

//    @Override
//    public void updateId() {
//        List<MaterielItemEntity> list = baseMapper.selectList(null);
//        UpdateWrapper<MaterielItemEntity> updateWrapper = new UpdateWrapper<MaterielItemEntity>();
//        String id = null;
//        for(MaterielItemEntity entity : list) {
//            updateWrapper.clear();
//            
//            id = entity.getName();
//            if(null != entity.getSpec()) {
//                id = id + entity.getSpec();
//            }
//            updateWrapper.set("id", FunctionUtils.md5L32(id));
//            updateWrapper.eq("pkid", entity.getPkid());
//            baseMapper.update(null, updateWrapper);
//        }
//    }

}
